package com.lvcoding.sec3.secdemo3.security;

import com.lvcoding.sec3.secdemo3.config.SysConfig;
import com.lvcoding.sec3.secdemo3.util.JwtUtil;
import com.lvcoding.sec3.secdemo3.util.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.PathContainer;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.pattern.PathPattern;
import org.springframework.web.util.pattern.PathPatternParser;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;

@Component
public class TokenFilter extends OncePerRequestFilter {

    @Autowired
    private SysConfig sysConfig;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        if(request.getRequestURI().contains("login") || request.getRequestURI().contains("auth/mobile")) {
            filterChain.doFilter(request, response);
            return;
        }

        List<String> ignoreTokenUrls = sysConfig.getIgnoreTokenUrls();
        if(!ignoreTokenUrls.isEmpty()) {
            boolean anyMatch = ignoreTokenUrls.stream().anyMatch(url -> {
                PathPatternParser pathPatternParser = new PathPatternParser();
                PathPattern pathPattern = pathPatternParser.parse(url);
                PathContainer pathContainer = PathContainer.parsePath(request.getRequestURI());
                boolean matches = pathPattern.matches(pathContainer);
                return matches;
            });
            if(anyMatch) {
                filterChain.doFilter(request, response);
                return;
            }
        }


        String token = request.getHeader("token");
        if(token == null) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            ResponseUtil.JsonResult(response, 401, "token不能为空", "");
            return;
        }

        boolean flag = JwtUtil.checkToken(token);
        if(!flag) {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            ResponseUtil.JsonResult(response, 401, "无效的token", "");
            return;
        }

        Map<String, Object> map = JwtUtil.parseToken(token);
        String username = (String) map.get("username");

        if(username.equalsIgnoreCase("admin")) {
            Collection<? extends GrantedAuthority> list = AuthorityUtils.createAuthorityList("cup:user:view","cup:user:add","cup:user:update","cup:user:delete");
            UsernamePasswordAuthenticationToken passwordAuthenticationToken = new UsernamePasswordAuthenticationToken(username, "admin", list);
            SecurityContextHolder.getContext().setAuthentication(passwordAuthenticationToken);
        }
        filterChain.doFilter(request, response);
    }
}
